package cn.tedu.lucky.draw.server.service.impl;

import cn.tedu.lucky.draw.server.common.enums.DrawEnum;
import cn.tedu.lucky.draw.server.common.enums.ErrorEnum;
import cn.tedu.lucky.draw.server.common.handler.DrawException;
import cn.tedu.lucky.draw.server.protrocol.po.*;
import cn.tedu.lucky.draw.server.protrocol.query.ActivityQuery;
import cn.tedu.lucky.draw.server.repository.*;
import cn.tedu.lucky.draw.server.service.IAtivityService;
import cn.tedu.lucky.draw.server.service.IPrizeService;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class AtivityServiceImpl implements IAtivityService {
    @Autowired
    private ActivityRepository activityRepository;

    @Autowired
    private ActivityRuleRepository activityRuleRepository;

    @Autowired
    private RuleRepository ruleRepository;

    @Autowired
    private ActivityResultRepository activityResultRepository;

    @Autowired
    private PrizeRepository prizeRepostiory;

    @Autowired
    private IPrizeService prizeService;

    List<Activity> activityList;

    @Override
    public List<Activity> getAll(ActivityQuery activityQuery) {
        if (activityList == null)
            activityList = activityRepository.findAll();
        String name = activityQuery.getName();
        Integer status = activityQuery.getStatus();

        return activityList.stream().filter(
                activity -> (name == null || name == "" || name.equals(activity.getName()))
        ).filter(
                activity -> (status == null || status.equals(activity.getStatus()))
        ).collect(Collectors.toList());
    }

    @Override
    public void save(Activity activity) {
        LocalDateTime now = LocalDateTime.now();
        activity.setCreateTime(now);
        activity.setUpdateTime(now);
        activity.setStatus(0);
        Activity save = activityRepository.save(activity);
        if (save == null) {
            throw new DrawException(ErrorEnum.SYSTEM_ERROR);
        }
        activityList = null;
    }

    @Override
    public Activity getActivtyById(Long id) {
        Optional<Activity> optional = activityRepository.findById(id);
        Activity activity = null;
        if (optional.isPresent()) {
            activity = optional.get();
        }
        return activity;
    }

    @Override
    public List<Activity> findAll() {
        Integer status = Integer.valueOf(DrawEnum.ENABLE.getCode());
        List<Activity> activityList = activityRepository.findByStatusEquals(status);
        return activityList;
    }

    @Override
    public Prize trigger(Long activityId) throws JSONException {
        //1.获取活动规则，检查用户权限
        List<ActivityRule> activityRules = activityRuleRepository.findByActivityId(activityId);
        List<Long> ids = activityRules.stream().map(ActivityRule::getRuleId).collect(Collectors.toList());
        List<Rule> rules = ruleRepository.findAllById(ids);
        boolean value = false;
        //1.1 遍历活动规则，检测抽奖次数
        for (Rule rule : rules) {
            //如果type=1，则当前规则用于限制用户的抽奖次数
            if (rule.getType() == 1) {
                //获取当前活动配置的抽奖次数
                JSONObject jsonObject = new JSONObject(rule.getContent());
                int count = jsonObject.getInt("count");
                //userId 应该是从当前登陆的用户身份中进行解析,目前假设是99999
                Integer results = activityResultRepository.countActivityResultsByActivityIdAndUserId(activityId, 99999L);
                if (results >= count) {
                    throw new DrawException(DrawEnum.TIMES_EXHAUSTED);
                }
            } else {
                //1.2 检测中奖概率是否降低
                JSONObject jsonObject = new JSONObject(rule.getContent());
                value = jsonObject.getBoolean("value");
            }
        }

        //获取奖品列表
        List<Prize> prizes = prizeService.findPrizeByActivityId(activityId);

        // 分配抽奖概率
        Map<Prize, Double> prizeProbabilityMap = new HashMap();
        double totalInverseValue = prizes.stream().mapToDouble(prize -> 1.0 / prize.getValue()).sum();

        // 如果需要降低概率，则所有概率值乘以一个小于1的因子
        double decreaseFactor = value ? 0.5 : 1.0;
        for (Prize prize : prizes) {
            double individualProbability = (1.0 / prize.getValue()) / totalInverseValue;
            prizeProbabilityMap.put(prize, individualProbability * decreaseFactor);
        }

        // 执行抽奖
        double randomValue = new Random().nextDouble();
        double cumulativeProbability = 0.0;
        for (Map.Entry<Prize, Double> entry : prizeProbabilityMap.entrySet()) {
            Prize prize = entry.getKey();
            Double probability = entry.getValue();

            cumulativeProbability += probability;
            if (randomValue <= cumulativeProbability) {
                prize.setStock(prize.getStock()-1);
                prizeRepostiory.save(prize);//更新奖品库存
                saveActivityResult(activityId,prize.getId());//记录中奖信息
                return prize; // 返回中奖的奖品对象
            }
        }
        // 如果没有抽中任何奖品
        Prize prize = new Prize();
        prize.setId(999999999L);
        prize.setName("谢谢参与");
        prize.setImg("https://img.tukuppt.com/png_preview/00/44/90/VDa2b4drT2.jpg%21/fw/780");
        saveActivityResult(activityId,prize.getId());

        return prize; // 根据业务需求返回默认奖品或处理为未中奖
    }

    private void saveActivityResult(Long activityId, Long prizeId) {
        ActivityResult activityResult = new ActivityResult();
        activityResult.setActivityId(activityId);
        activityResult.setUserId(99999L);
        activityResult.setPrizeId(prizeId);
        activityResult.setStatus(0);//未发放
        activityResult.setWinTime(LocalDateTime.now());
        activityResultRepository.save(activityResult);
    }
}
